from scapy.all import rdpcap, IP, TCP, UDP, Raw
import re
def extract_payloads(file_path):
    packets = rdpcap(file_path)
    payloads = []

    for pkt in packets:
        if IP in pkt and (TCP in pkt or UDP in pkt) and Raw in pkt:
            ip = pkt[IP]
            transport = pkt[TCP] if TCP in pkt else pkt[UDP]

            src_ip = ip.src
            dst_ip = ip.dst
            src_port = transport.sport
            dst_port = transport.dport
            proto = 'TCP' if TCP in pkt else 'UDP'

            # 获取应用层载荷
            payload_bytes = pkt[Raw].load
            try:
                payload_str = payload_bytes.decode('utf-8', errors='ignore')  # 忽略无法解码的字符
            except Exception as e:
                payload_str = f"[非文本载荷，无法解码: {e}]"

            payloads.append({
                "src_ip": src_ip,
                "dst_ip": dst_ip,
                "src_port": src_port,
                "dst_port": dst_port,
                "protocol": proto,
                "payload": payload_str
            })

    return payloads


def detect_sqli(payload):
    # 使用正则匹配 SQL 注入特征
    sqli_signatures = r"(?:')|(?:--)|(/\\*)|(\b(SELECT|UPDATE|DELETE|INSERT|DROP|UNION|EXEC|OR)\b)"
    if re.search(sqli_signatures, payload, re.IGNORECASE):
        return True
    return False


def analyze_pcap_with_payload(file_path):
    payloads = extract_payloads(file_path)
    print(payloads)
    print(f"Total application payloads extracted: {len(payloads)}")
    sqli_count = 0

    for i, item in enumerate(payloads):
        payload = item['payload']
        if detect_sqli(payload):
            sqli_count += 1
            print(f"\n[SQL Injection Detected] Flow: {item['src_ip']}:{item['src_port']} -> {item['dst_ip']}:{item['dst_port']} ({item['protocol']})")
            print(f"Payload:\n{payload[:500]}...")  # 打印前500字符避免输出过长

    print(f"\nTotal potential SQL injection payloads found: {sqli_count}")


# 调用函数分析 pcap 文件
#analyze_pcap_with_payload("E:\\workplace\\文档管理\\拨测工具\\第二轮提测\\物联网-评测检测工具样包 20230818 v1.9(1)\\0109注入攻击\\sql_injection_0.pcap")
analyze_pcap_with_payload("E:\\13.20230718.00080.pcap")